package com.sfpay.coreplatform.member.service.impl;

 
import java.sql.SQLException;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sfpay.coreplatform.account.valueobject.dto.OpenAcc;
import com.sfpay.coreplatform.account.valueobject.dto.OpenAccReturn;
import com.sfpay.coreplatform.member.common.MemberResponseCode;
import com.sfpay.coreplatform.member.common.constant.Constants;
import com.sfpay.coreplatform.member.common.enums.AcctUseFlag;
import com.sfpay.coreplatform.member.common.enums.CertType;
import com.sfpay.coreplatform.member.common.enums.ChannelCode;
import com.sfpay.coreplatform.member.common.enums.DealerFlag;
import com.sfpay.coreplatform.member.common.enums.MemberLockStatus;
import com.sfpay.coreplatform.member.common.enums.MemberStatus;
import com.sfpay.coreplatform.member.common.enums.MemberType;
import com.sfpay.coreplatform.member.common.enums.OperatorStatus;
import com.sfpay.coreplatform.member.common.enums.SafeFlag;
import com.sfpay.coreplatform.member.common.util.AccountUtil;
import com.sfpay.coreplatform.member.common.util.EncryptUtil;
import com.sfpay.coreplatform.member.common.util.StringUtil;
import com.sfpay.coreplatform.member.persistence.dao.IMemberAccountManageDao;
import com.sfpay.coreplatform.member.persistence.dao.IMemberManageDao;
import com.sfpay.coreplatform.member.persistence.dao.IOperatorManagerDao;
import com.sfpay.coreplatform.member.persistence.dao.IPersonManageDao;
import com.sfpay.coreplatform.member.service.IPersonService;
import com.sfpay.coreplatform.member.service.exception.MemberServiceException;
import com.sfpay.coreplatform.member.service.inner.IMemberHelpService;
import com.sfpay.coreplatform.member.service.proxy.account.IAcctProxyManageService;
import com.sfpay.coreplatform.member.service.validate.BussineValidate;
import com.sfpay.coreplatform.member.service.validate.CommonCheckUtil;
import com.sfpay.coreplatform.member.service.validate.ValidateUtil;
import com.sfpay.coreplatform.member.valueobject.dto.Member;
import com.sfpay.coreplatform.member.valueobject.dto.MemberAccount;
import com.sfpay.coreplatform.member.valueobject.dto.PersonMember;
import com.sfpay.coreplatform.member.valueobject.tmo.MemberInfo;
import com.sfpay.coreplatform.member.valueobject.tmo.OperatorInfo;

@Service
public class PersonServiceImpl implements IPersonService
{
	private static Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);

	@Resource
	private IMemberManageDao memberManageDao;
	
	@Resource
	private IPersonManageDao personManageDao;
	
	@Resource
	private IOperatorManagerDao operatorManagerDao;
	
	@Resource
	private IMemberAccountManageDao memberAccountManageDao;
	
	@Resource
	private IMemberHelpService memberHelpService;
	
	@Resource
	private IAcctProxyManageService acctProxyManageService;
	
	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public void updateLoginPwd(String loginId, String oldPwd, String newPwd,int loginType,
			MemberType memberType) throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:updateLoginPwd,update loginpwd for person member,the parameters 's info"
					+ "{loginId:" + loginId + ",oldPwd:" + oldPwd + ",newPwd:"+ newPwd 
					+ ",loginType:" + loginType + ",memberType:" + memberType +"}");
		}
		
		// 校验参数信息
		ValidateUtil.checkLoginType(loginId, loginType);
		ValidateUtil.checkParamIsNull(oldPwd, "oldPwd");
		ValidateUtil.checkParamIsNull(newPwd, "newPwd");
		if (oldPwd.equals(newPwd))
		{
			throw new MemberServiceException(MemberResponseCode.INVALID_PWD,"new password can not same as old password");
		}
		else if(memberType == null || MemberType.PERSON != memberType)
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ERR_FORMAT,
					"memberType must be 'PERSON'");
		}

		// 根据标示查询当前会员信息
		Member member = null;
		try 
		{
			member = memberManageDao.queryPersonBaseInfoByType(loginId,loginType,memberType);
			BussineValidate.checkMemberStatus(member);
			//比较旧密码是否正确
			if (!member.getPwd().equals(EncryptUtil.encryptPwd(oldPwd))) 
			{
				throw new MemberServiceException(MemberResponseCode.INVALID_PWD,"old password does not match");
			}
			//更新操作员密码
			int counts = operatorManagerDao.updateOperatorLoginPwd(member.getMobile(), member.getEmail(),
					member.getLoginName(),memberType, member.getPwd(), EncryptUtil.encryptPwd(newPwd));
			if(counts != 1)
			{
				throw new MemberServiceException(MemberResponseCode.CAN_NOT_REPEAT_REQUEST,"can not repeat request");
			}
		}
		catch (Exception e) 
		{
			logger.error("method:updateLoginPwd,update loginpwd for person member error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"update data occur exception", e);
		}
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:updateLoginPwd,update loginpwd for person member successful!,the parameters 's info"
					+ "{loginId:" + loginId + ",oldPwd:" + oldPwd + ",newPwd:"+ newPwd 
					+ ",loginType:" + loginType + ",memberType:" + memberType +"}");
		}
	}

	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public void resetLoginPwd(String loginId, String newPwd, int loginType,	MemberType memberType) throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:resetLoginPwd,resetloginpwd for person member,the parameters 's info"
					+ "{loginId:" + loginId + ",newPwd:"+ newPwd + ",loginType:" + loginType + ",memberType:" + memberType +"}");
		}
		
		// 校验参数信息
		ValidateUtil.checkLoginType(loginId, loginType);
		ValidateUtil.checkParamIsNull(newPwd, "newPwd");
		if(memberType == null || MemberType.PERSON != memberType)
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ERR_FORMAT,
					"memberType must be persion");
		}

		// 根据标示查询当前会员信息
		Member member = null;
		try 
		{
			member = memberManageDao.queryPersonBaseInfoByType(loginId,loginType,memberType);
			BussineValidate.checkMemberStatus(member);
			//重置操作员密码
			int counts = operatorManagerDao.updateOperatorLoginPwd(member.getMobile(), member.getEmail(),
					member.getLoginName(),memberType, member.getPwd(), EncryptUtil.encryptPwd(newPwd));
			if(counts != 1)
			{
				throw new MemberServiceException(MemberResponseCode.CAN_NOT_REPEAT_REQUEST,"can not repeat request");
			}
		}
		catch (Exception e) 
		{
			logger.error("method:resetLoginPwd,resetloginpwd for person member error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"update data occur exception", e);
		}
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:resetLoginPwd,resetloginpwd for person member successful!,the parameters 's info"
					+ "{loginId:" + loginId + ",newPwd:"+ newPwd + ",loginType:" + loginType + ",memberType:" + memberType +"}");
		}
	}

	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public long register(PersonMember member) throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:register,person member register,the parameters 's info"
					+ "{member:" + member + "}");
		}
		//参数校验
		validPersonRegedit(member);
		long memberNo = 0L;
		
		try 
		{
			// 验证个人会员的手机号,邮箱，登入名，证件信息是否已经存在
			memberHelpService.queryOperatorIsExist(member);
			// 个人注册会员
			memberNo = memberHelpService.generateMemberNo(member.getMemberType(), member.getChannel());
			//插入会员主表
			MemberInfo memberInfo = new MemberInfo();
			memberInfo.setMemberNo(memberNo);
			memberInfo.setMemberType(member.getMemberType());
			memberInfo.setMemberName(member.getMemberName());
			memberInfo.setStatus(MemberStatus.NORMAL);//会员状态为正常NORMAL--会员只存在正常和注销状态
			memberInfo.setCertNo(member.getCertNo());
			memberInfo.setCertTypeCode(member.getCertType());
			memberInfo.setCertValidBeginDate(member.getCertValidBeginDate());
			memberInfo.setCertValidEndDate(member.getCertValidEndDate());
			memberInfo.setDealerFlag(member.getDealerFlag() == null ? DealerFlag.GENERAL : member.getDealerFlag());
			memberInfo.setNameAuthFlag(StringUtil.isStrNull(member.getNameAuthFlag())? "Y" : member.getNameAuthFlag());//N:实名用户,Y非实名用户
			memberInfo.setMemberSrc(member.getMemberSource());
			memberInfo.setActive(member.getActive());
			memberInfo.setChannel(ChannelCode.valueOf(member.getChannel()));
			//表中已经不用字段设置默认值：安全级别，会员来源
			memberInfo.setSafeFlag(SafeFlag.BASIC);
			memberInfo.setSysSource("PAY_SYS");
			memberManageDao.addMemberInfo(memberInfo);
			
			//插入会员扩展表
			member.setMemberNo(memberNo);
			personManageDao.addMemberPersonExts(member);
			
			//插入操作员表
			OperatorInfo operatorInfo = new OperatorInfo();
			operatorInfo.setEmail(member.getEmail());
			operatorInfo.setLoginName(member.getLoginName());
			operatorInfo.setMemberNo(memberNo);
			operatorInfo.setMobile(member.getMobile());
			operatorInfo.setOperatorType("PERSON");
			operatorInfo.setPwd(EncryptUtil.encryptPwd(member.getPwd()));
			operatorInfo.setStatus(OperatorStatus.YCHECK); //个人默认是已审核状态
			operatorInfo.setTelephone(member.getOperTelephone());
			operatorInfo.setLockStatus(MemberLockStatus.NORMAL);
			operatorManagerDao.addOperatorInfo(operatorInfo);
			
			//若是商户，这开通本金虚户(默认与会员登入密码一致)
			if(DealerFlag.DEALER == member.getDealerFlag())
			{
				//调用账户，添加虚户（账户未激活）
				OpenAcc openAcc = AccountUtil.addMemberVirtualAcc(memberNo, EncryptUtil.encryptPwd(member.getPwd()), Constants.ACCOUNT_TYPE_NO_FOR_101);
				OpenAccReturn openAccReturn = acctProxyManageService.openAccount(openAcc);
				
				//添加会员与账户映射关系
				MemberAccount memberAccount = new MemberAccount();
				memberAccount.setAccountNo(openAccReturn.getAccountNo());
				memberAccount.setMemberNo(openAccReturn.getMemberNo());
				memberAccount.setAccountType(Constants.ACCOUNT_TYPE_NO_FOR_101);
				memberAccount.setDefaultAcctFlag(Constants.COMM_Y);//是否资金账户
				memberAccount.setProductType("VA");//产品类型 虚拟卡
				memberAccount.setAcctUseFlag(AcctUseFlag.DEFAULT);
				memberAccount.setBussineProductType("VA");
				memberAccountManageDao.addMemberAccountInfo(memberAccount);
				
				//激活账户
				try
				{
					acctProxyManageService.makeAccountActive(openAccReturn.getAccountNo());
				}
				catch(Exception e)
				{
					logger.error("method:register:makeAccountActive, active person member's normal account active error", e);
				}
			}
		} 
		catch (MemberServiceException e) 
		{
			logger.error("method:registerMember,member register . error", e);
			throw e;
		} 
		catch (Exception e) 
		{
			logger.error("method:registerMember,member register . error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,
					"insert data occur exception", e);
		}
		
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:registerMember,person member register successful!,the parameters 's info"
					+ "{member:" + member + "}");
		}
		return memberNo;
	}
	/**
	 * 
	 *
	 * 方法说明：个人会员注册参数校验
	 *
	 * @param member
	 * @throws MemberServiceException
	 */
	private void validPersonRegedit(PersonMember member) throws MemberServiceException
	{
		if(StringUtil.isStrNull(member.getMobile()) && StringUtil.isStrNull(member.getEmail())
				&& StringUtil.isStrNull(member.getLoginName()))
		{
			throw new MemberServiceException(MemberResponseCode.INVALID_LEAST_ONE_VALUE,"the Parameter mobile, email, login name at least a parameter value");
		}
		else if(!StringUtil.isStrNull(member.getMobile()) && !CommonCheckUtil.checkMobile(member.getMobile()))
		{
			throw new MemberServiceException(MemberResponseCode.INVALID_MOBILE,"the Parameter mobile format is incorrect");
		}
		else if(!StringUtil.isStrNull(member.getEmail()) && !CommonCheckUtil.checkMail(member.getEmail()))
		{
			throw new MemberServiceException(MemberResponseCode.INVALID_MAIL,"the Parameter email format is incorrect");
		}
		if(StringUtil.isStrNull(member.getPwd()))
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter pssword can not be empty");
		}
		else if(member.getMemberType() == null) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter member type can not be empty");
		}
		else if(MemberType.PERSON != member.getMemberType())
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ERR_FORMAT,"the Parameter person member type must be 'PERSON' ");
		}
		else if(StringUtil.isStrNull(member.getChannel())) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter member channel can not be empty ");
		}
		else if(StringUtil.isStrNull(member.getRegType()))
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter member regedit type can not be empty ");
		}
		else if(StringUtil.isStrNull(member.getMemberName())) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter member name can not be empty ");
		}
		else if(member.getCertType() == null) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter cert type can not be empty ");
		}
		else if(StringUtil.isStrNull(member.getCertNo()))
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the Parameter cert No. can not be empty ");
		}
	}

	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public void update(PersonMember modifyInfo) throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:update,person member modify info,the parameters 's info"
					+ "{modifyInfo:" + modifyInfo + "}");
		}
		if(null == modifyInfo)
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL,"the parameter modifyInfo must not be empty");
		}
		ValidateUtil.checkMemberNo(modifyInfo.getMemberNo());
		if(!StringUtil.isStrNull(modifyInfo.getMobile()))
		{
			ValidateUtil.checkMobile(modifyInfo.getMobile());
		}
		else if(!StringUtil.isStrNull(modifyInfo.getEmail()))
		{
			ValidateUtil.checkEmail(modifyInfo.getEmail());
		}
		else if(!StringUtil.isStrNull(modifyInfo.getNameAuthFlag()) &&
				!StringUtil.isArbitrarilyEqual(modifyInfo.getNameAuthFlag(),
						Constants.COMM_Y,Constants.COMM_N))
		{
			//用户实名认证标志Y,N
			throw new MemberServiceException(MemberResponseCode.INVALID_NAME_AUTHFLAG,"the Parameter user real-name certification identifies illegal");
		}

		try 
		{
			// 获取当前会员的信息
			Member member = memberManageDao.queryMemberByMemberNo(modifyInfo.getMemberNo());
			BussineValidate.checkMemberStatus(member);
			boolean modifyImportInfo = false;
			Member midifyMember = new Member();
			midifyMember.setMemberType(MemberType.PERSON);
			if (!StringUtil.isStrNull(member.getMobile()) && !member.getMobile().equals(modifyInfo.getMobile())) 
			{
				modifyImportInfo = true;
				midifyMember.setMobile(modifyInfo.getMobile());
			}
			if (!StringUtil.isStrNull(member.getEmail()) && !member.getEmail().equals(modifyInfo.getEmail()))
			{
				modifyImportInfo = true;
				midifyMember.setEmail(modifyInfo.getEmail());
			}
			if(!StringUtil.isStrNull(member.getLoginName()) 
					&& !member.getLoginName().equals(modifyInfo.getLoginName())) 
			 {
				 midifyMember.setLoginName(modifyInfo.getLoginName()); 
			 }
			
			if (member.getCertType() != null && member.getCertType() != modifyInfo.getCertType()) 
			{
				modifyImportInfo = true;
				midifyMember.setCertType(modifyInfo.getCertType());
			}

			if (!StringUtil.isStrNull(member.getCertNo()) && !member.getCertNo().equals(modifyInfo.getCertNo())) 
			{
				modifyImportInfo = true;
				midifyMember.setCertNo(modifyInfo.getCertNo());
			}
			//已经实名认证后，不能修改信息
			if(Constants.COMM_N.equals(member.getNameAuthFlag()) && modifyImportInfo)
			{
				throw new MemberServiceException(MemberResponseCode.CANNOT_MODIFYINFO_AFTER_NAMEAUTH,"can not modify mobile,mail,loginName,certType,certNo after name auth");
			}
			 //校验修改后的会员（手机，邮箱，登入名，证件类型+证件号码）是否已经存在
			if(modifyImportInfo)
			{
				memberHelpService.queryOperatorIsExist(midifyMember);
			}
			// 修改会员主表信息
			MemberInfo memberInfo = new MemberInfo();
			memberInfo.setActive(modifyInfo.getActive());
			memberInfo.setChannel(ChannelCode.valueOf(modifyInfo.getChannel()));
			memberInfo.setDealerFlag(modifyInfo.getDealerFlag());
			memberInfo.setMemberName(modifyInfo.getMemberName());
			memberInfo.setMemberNo(modifyInfo.getMemberNo());
			memberInfo.setMemberSrc(modifyInfo.getMemberSource());
			memberInfo.setNameAuthFlag(modifyInfo.getNameAuthFlag());
			memberInfo.setCertTypeCode(modifyInfo.getCertType());
			memberInfo.setCertNo(modifyInfo.getCertNo());
			memberInfo.setCertValidBeginDate(modifyInfo.getCertValidBeginDate());
			memberInfo.setCertValidEndDate(modifyInfo.getCertValidEndDate());

			// 修改操作员信息
			OperatorInfo operatorInfo = new OperatorInfo();
			operatorInfo.setEmail(modifyInfo.getEmail());
			operatorInfo.setLoginName(modifyInfo.getLoginName());
			operatorInfo.setMemberNo(modifyInfo.getMemberNo());
			operatorInfo.setMobile(modifyInfo.getMobile());
			operatorInfo.setTelephone(modifyInfo.getOperTelephone());
			
			// 更新会员表
			memberManageDao.updateMemberInfoByMemberNo(memberInfo);

			// 更新会员扩展表
			personManageDao.updatePersonExtsByMemberNo(modifyInfo);

			// 更新操作员表
			operatorManagerDao.updatePersonOperatorByMemberNo(operatorInfo);
		} 
		catch (Exception e) 
		{
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"update data occur exception", e);
		}
		
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:update,person member modify info successful,the parameters 's info"
					+ "{modifyInfo:" + modifyInfo + "}");
		}
	}

	@Override
	@Transactional(readOnly=true)
	public PersonMember queryPersionMemberByMbrNo(Long memberNo) throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:queryPersionMemberByMbrNo,query person member by memberNo ,the parameters 's info"
					+ "{memberNo:" + memberNo + "}");
		}
		
		// 校验参数信息
		ValidateUtil.checkMemberNo(memberNo);

		// 根据标示查询当前会员信息
		PersonMember member = null;
		try 
		{
			member = memberManageDao.queryPersonMemberByMemberNo(memberNo);
			if(member != null)
			{
				member.setPwd("");
			}
		}
		catch(Exception e)
		{
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"query data occur exception", e);
		}
		
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:queryPersionMemberByMbrNo,query person member by memberNo successful,the parameters 's info"
					+ "{memberNo:" + memberNo + "}");
		}
		return member;
	}

	@Override
	@Transactional(readOnly=true)
	public PersonMember queryPersionMemberInfo(String loginId, int loginType)
			throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:queryPersionMemberInfo,person member login by loginType,the parameters 's info"
					+ "{loginId:" + loginId + ",loginType:" + loginType + "}");
		}
		
		// 校验参数信息
		ValidateUtil.checkLoginType(loginId, loginType);

		// 根据标示查询当前会员信息
		PersonMember member = null;
		try 
		{
			member = memberManageDao.queryPersonInfoByType(loginId,loginType);
			if(member != null)
			{
				member.setPwd("");
			}
		}
		catch (Exception e) 
		{
			logger.error("method:queryPersionMemberInfo,person member login by loginType error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"query data occur exception", e);
		}
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:queryPersionMemberInfo,person member login by loginType successful!,the parameters 's info"
					+ "{loginId:" + loginId + ",loginType:" + loginType + "}");
		}
		return member;
	}

	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public PersonMember loginPerson(String loginId, String password, int loginType) 
			throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.debug("method:loginPerson,person member login ,the parameters 's info"
					+ "{loginId:" + loginId + ",password:" + password + ",loginType:" + loginType + "}");
		}
		
		// 校验参数信息
		ValidateUtil.checkLoginType(loginId, loginType);
		ValidateUtil.checkParamIsNull(password, "password");

		// 根据标示查询当前会员信息
		PersonMember member = null;
		try 
		{
			member = memberManageDao.queryPersonInfoByType(loginId,loginType);
			BussineValidate.checkMemberStatus(member);
			
			//会员登录信息验证
			//第三次输入错误，需要提示****超过N次，请******
			Map<String ,Integer> map = memberHelpService.authMemberLogin(password, member.getMobile(),member.getEmail(),member.getLoginName(),MemberType.PERSON);
			//member为false的时候,即账户密码不正确
			int tryTimes =  map.get("tryTimes");
			if(Constants.TRY_TIMES_3 == tryTimes)
			{
				throw new MemberServiceException(MemberResponseCode.BEYOND_MAX_LOGINFAIL_TIMES,"member's old password is wrong and beyond max try times");
			}
			else if(Constants.TRY_TIMES_2 == tryTimes)
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_PASSWORDIS_INVALID_SECOND,"second login fail");//第二次失败
			}
			else if(Constants.TRY_TIMES_1 == tryTimes)
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_PASSWORDIS_INVALID,"first login fail");//第一次失败
			}
			member.setPwd("");
		} 
		catch (MemberServiceException e) 
		{
			logger.error("method:loginPerson,preson member login error ", e);
			throw e;
		}
		catch (Exception e) 
		{
			logger.error("method:loginPerson,person member login error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"query data occur exception", e);
		}
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:loginPerson,person member login successful!,the parameters 's info"	
					+ "{loginId:" + loginId + ",password:" + password + ",loginType:" + loginType + "}");
		}
		return member;
	}
	
	/**
	 * 个人会员开通本金账户
	 */
	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public Long openNormalPrincipalAccount(Long memberNo, String productType, String subjectNo, 
			String payPassword,Long overdraftLimitAmt) throws MemberServiceException 
	{
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:openNormalPrincipalAccount,person member open normal account,the parameters 's info"	
					+ "{memberNo:" + memberNo + ",productType:" + productType + ",payPassword:" + payPassword
					+ ",overdraftLimitAmt:"+  overdraftLimitAmt + "}");
		}
		// 1、参数合法性校验
		if (StringUtil.isObjectNull(memberNo) || StringUtil.isStrNull(productType)) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL, "参数为空");
		}
		// 会员信息校验
		PersonMember personMember = validateMember(memberNo);
		// 2、生成资金账户开户请求参数
		if(StringUtil.isStrNull(payPassword)) 
		{
			// 获取登陆密码作为账户密码
			payPassword = personMember.getPwd();
		}
		OpenAccReturn openAccReturn = null;
		try
		{
			// 调用账户开户，账户状态为未激活
			OpenAcc openAcc = AccountUtil.getDefaultAccount(memberNo, payPassword);
			openAcc.setSubjectNo(subjectNo);
			openAcc.setOverdraftAmountLimit(overdraftLimitAmt);
			// 3、调用账户系统开户
			openAccReturn = acctProxyManageService.openAccount(openAcc);
			// 生成会员账户关联实体，并保存至数据库
			MemberAccount memberAccount = AccountUtil.makeMemberAccountFor101(openAccReturn.getAccountNo(), memberNo, productType, AcctUseFlag.DEFAULT);
			memberAccountManageDao.addMemberAccountInfo(memberAccount);
			
			//激活账户
			try
			{
				acctProxyManageService.makeAccountActive(openAccReturn.getAccountNo());
			}
			catch(Exception e)
			{
				logger.error("method:openNormalPrincipalAccount:makeAccountActive, active member's normal account active error", e);
			}
		} 
		catch (MemberServiceException e) 
		{
			logger.error("method:openNormalPrincipalAccount, open normal account error", e);
			throw e;
		} 
		catch (Exception e) 
		{
			logger.error("method:openNormalPrincipalAccount, open normal account error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION, "save db occur error", e);
		}
		
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:openNormalPrincipalAccount,person member open normal account successful,the parameters 's info"	
					+ "{memberNo:" + memberNo + ",productType:" + productType + ",payPassword:" + payPassword + "}");
		}
		return openAccReturn.getAccountNo();

		
	}

	/**
	 * 个人会员开通积分账户
	 */
	@Override
	@Transactional(rollbackFor= MemberServiceException.class,propagation=Propagation.REQUIRED)
	public Long openSFPAccount(Long memberNo, String productType, String payPassword) 
			throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:openSFPAccount,person member open JF account,the parameters 's info"	
					+ "{memberNo:" + memberNo + ",productType:" + productType + ",payPassword:" + payPassword + "}");
		}
		// 1、参数合法性校验
		if (StringUtil.isObjectNull(memberNo) || StringUtil.isStrNull(productType)) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL, "参数为空");
		}
		// 会员信息校验
		PersonMember personMember = validateMember(memberNo);
		// 2、生成资金账户开户请求参数
		if(StringUtil.isStrNull(payPassword)) 
		{
			// 获取登陆密码作为账户密码
			payPassword = personMember.getPwd();
		}
		OpenAccReturn openAccReturn = null;
		
		try 
		{
			OpenAcc openAcc = AccountUtil.getJFAccount(memberNo, payPassword);
			// 调用账户开户，账户状态为未激活
			// 3、调用账户系统开户
			openAccReturn = acctProxyManageService.openAccount(openAcc);
			// 生成会员账户关联实体，并保存至数据库
			MemberAccount memberAccount = AccountUtil.makeMemberAccountFor102(openAccReturn.getAccountNo(), 
					memberNo, productType, AcctUseFlag.DEFAULT);
			memberAccountManageDao.addMemberAccountInfo(memberAccount);
			
			//激活账户
			try
			{
				acctProxyManageService.makeAccountActive(openAccReturn.getAccountNo());
			}
			catch(Exception e)
			{
				logger.error("method:openSFPAccount:makeAccountActive, active member's sfp account active error", e);
			}
		} 
		catch (MemberServiceException e) 
		{
			logger.error("method:openSFPAccount, open point account error", e);
			throw e;
		} 
		catch (Exception e) 
		{
			logger.error("method:openSFPAccount, open point account error", e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION, "save db occur error", e);
		}
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:openSFPAccount,person member open JF account successful!,the parameters 's info"	
					+ "{memberNo:" + memberNo + ",productType:" + productType + ",payPassword:" + payPassword + "}");
		}
		return openAccReturn.getAccountNo();
	}
	
	/**
	 * 个人会员信息校验(校验会员是否存在)
	 * @param memberNo
	 * @throws MemberServiceException
	 */
	private PersonMember validateMember(Long memberNo) throws MemberServiceException {
		// 会员信息校验
		PersonMember personMember;
		try 
		{
			personMember = memberManageDao.queryPersonMemberByMemberNo(memberNo);
		} 
		catch (Exception e) 
		{
			logger.error("method:validateMember,query person member by memberNo error",e);
			if(SQLException.class.isInstance(e.getCause()))
			{
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION, "query db occur error", e);
		}
		if(null == personMember)
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_NOT_EXIST, "person member is not exists!");
		}
		return personMember;
	}

	@Override
	public PersonMember queryPersionMemberInfoByCert(CertType certType,	String certNo)
			throws MemberServiceException
	{
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:queryPersionMemberInfoByCert,query person member by certtype and certno,the parameters 's info"	
					+ "{certType:" + certType + ",certNo:" + certNo + "}");
		}
		//参数校验
		if (StringUtil.isObjectNull(certType) || StringUtil.isStrNull(certNo)) 
		{
			throw new MemberServiceException(MemberResponseCode.MEMBER_COMMON_PARAM_ISNULL, "the parameter certtype or cert.no is null");
		}
		PersonMember personMember = null;
		try 
		{
			personMember = memberManageDao.queryPersionMemberInfoByCert(certType,certNo);
			if(personMember != null)
			{
				personMember.setPwd("");
			}
		} 
		catch (Exception e) 
		{
			logger.error("method:queryPersionMemberInfoByCert,query person member by certtype and certno error", e);
			if(SQLException.class.isInstance(e.getCause())){
				throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION,"" + ((SQLException)(e.getCause())).getErrorCode(),e);
			}
			throw new MemberServiceException(MemberResponseCode.MEMBER_DB_EXCEPTION, "query db occur exception", e);
		}
		
		if (logger.isDebugEnabled()) 
		{
			logger.info("method:queryPersionMemberInfoByCert,query person member by certtype and certno successful!,the parameters 's info"	
					+ "{certType:" + certType + ",certNo:" + certNo + "}");
		}
		return personMember;
	}
}
